/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.ppm.gtm.congestion;

import bgu.ppm.gtm.base.ImmutableStrategy;
import bgu.ppm.gtm.base.StrategyProfile;
import bgu.sonar.util.collections.Pair;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author User
 */
public class CongestionStrategyProfile implements StrategyProfile {

    private int[] congestions;
    private Map<Integer, ImmutableStrategy> strategies;

    public CongestionStrategyProfile(int numberOfResources, ImmutableStrategy... s) {
        strategies = new HashMap<>();
        congestions = new int[numberOfResources];
        insertStrategies(s);
    }

    public CongestionStrategyProfile(int numberOfResources, Collection<ImmutableStrategy> s) {
        this(numberOfResources, s.toArray(new ImmutableStrategy[s.size()]));
    }

    public CongestionStrategyProfile(CongestionStrategyProfile from, ImmutableStrategy... s) {
        congestions = Arrays.copyOf(from.congestions, from.congestions.length);
        strategies = new HashMap<>(from.strategies);
        insertStrategies(s);
    }

    public int getCongestionForResource(int resource) {
        return congestions[resource];
    }

    public int getCongestionForResourceWithoutPlayer(int resource, int player) {
        return Math.max(congestions[resource] + (strategies.containsKey(player) ? -strategies.get(player).get(resource) : 0), 0);
    }

    @Override
    public ImmutableStrategy getSelectedStrategy(int player) {
        return strategies.get(player);
    }

    @Override
    public Iterator<Pair<Integer, ImmutableStrategy>> iterator() {
        return new Iterator<Pair<Integer, ImmutableStrategy>>() {
            Iterator<Map.Entry<Integer, ImmutableStrategy>> i = strategies.entrySet().iterator();

            @Override
            public boolean hasNext() {
                return i.hasNext();
            }

            @Override
            public Pair<Integer, ImmutableStrategy> next() {
                Map.Entry<Integer, ImmutableStrategy> p = i.next();
                return new Pair<>(p.getKey(), p.getValue());
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Not supported.");
            }
        };
    }

    private void insertStrategies(ImmutableStrategy[] s) {
        for (ImmutableStrategy strategy : s) {
            if (strategies.containsKey(strategy.getOwningPlayer())) {
                for (Pair<Integer, Integer> p : strategies.get(strategy.getOwningPlayer())) {
                    congestions[p.getX()] -= p.getY();
                }
            }
            for (Pair<Integer, Integer> p : strategy) {
                congestions[p.getX()] += p.getY();
            }
            strategies.put(strategy.getOwningPlayer(), strategy);
        }
    }
}
